﻿
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;

namespace Web.UI.TypeExtensions
{
    public static class TagBuilderExtensions
    {
        public static TagBuilder New(string tagName)
        {
            return new TagBuilder(tagName);
        }

        #region Attribute

        public static TagBuilder Attribute(this TagBuilder source, string attribute, string value, bool replaceExisting = false)
        {
            source.MergeAttribute(attribute, value, replaceExisting);
            return source;
        }

        public static TagBuilder Attribute(this TagBuilder source, string attribute, IHtmlString html, bool replaceExisting = false)
        {
            return Attribute(source, attribute, html.ToString(), replaceExisting);
        }

        #endregion

        #region Class

        public static TagBuilder Class(this TagBuilder source, string @class)
        {
            source.AddCssClass(@class);
            return source;
        }

        #endregion

        #region Html

        public static TagBuilder Html(this TagBuilder source, string html)
        {
            source.InnerHtml = html;
            return source;
        }

        public static TagBuilder Html(this TagBuilder source, TagBuilder tag)
        {
            return Html(source, tag.ToString());
        }

        public static TagBuilder Html(this TagBuilder source, IHtmlString html)
        {
            return Html(source, html.ToString());
        }

        #endregion

        #region AppendHtml

        public static TagBuilder AppendHtml(this TagBuilder source, string html)
        {
            if (source.InnerHtml == null)
                source.InnerHtml = string.Empty;
            source.InnerHtml += html;
            return source;
        }

        public static TagBuilder AppendHtml(this TagBuilder source, TagBuilder tag)
        {
            return AppendHtml(source, tag.ToString());
        }

        public static TagBuilder AppendHtml(this TagBuilder source, IHtmlString html)
        {
            if (html == null)
            {
                return source;
            }
            return AppendHtml(source, html.ToString());
        }

        #endregion

        #region PrependHtml

        public static TagBuilder PrependHtml(this TagBuilder source, string html)
        {
            if (source.InnerHtml == null)
                source.InnerHtml = string.Empty;
            source.InnerHtml = html + source.InnerHtml;
            return source;
        }

        public static TagBuilder PrependHtml(this TagBuilder source, TagBuilder tag)
        {
            return PrependHtml(source, tag.ToString());
        }

        public static TagBuilder PrependHtml(this TagBuilder source, IHtmlString html)
        {
            return PrependHtml(source, html.ToString());
        }

        #endregion

        public static MvcHtmlString ToHtml(this TagBuilder source)
        {
            return MvcHtmlString.Create(source.ToString());
        }

        public static MvcHtmlString ToHtml(this TagBuilder source, TagRenderMode renderMode)
        {
            return MvcHtmlString.Create(source.ToString(renderMode));
        }

        public static TagBuilder MergeHtmlAttributes(this TagBuilder tb, IDictionary<string, object> htmlAttributes)
        {
            if (htmlAttributes == null)
            {
                throw new ArgumentNullException("htmlAttributes");
            }
            foreach (var current in htmlAttributes)
            {
                if (!tb.Attributes.ContainsKey(current.Key))
                {
                    tb.Attributes.Add(current.Key, (current.Value != null) ? current.Value.ToString() : string.Empty);
                }
                else
                {
                    if (current.Key.ToLower() == "class")
                    {
                        tb.Attributes[current.Key] = tb.Attributes[current.Key] + " " + current.Value;
                    }
                    else
                    {
                        tb.Attributes[current.Key] = ((current.Value != null) ? current.Value.ToString() : string.Empty);
                    }
                }
            }
            return tb;
        }

        public static TagBuilder AddOrMergeCssClass(this TagBuilder tb, bool condition, string attrValue)
        {
            return !condition ? tb : AddOrMergeAttribute(tb, "class", attrValue);
        }

        public static TagBuilder AddOrMergeCssClass(this TagBuilder tb, string attrValue)
        {
            return AddOrMergeAttribute(tb, "class", attrValue);
        }

        public static TagBuilder AddOrMergeAttribute(this TagBuilder tb, string attrName, string attrValue)
        {
            if (tb.Attributes.ContainsKey(attrName))
            {
                if (!tb.Attributes[attrName].Contains(attrValue))
                {
                    tb.Attributes[attrName] += " " + attrValue;
                }
            }
            else
            {
                tb.Attributes.Add(attrName, attrValue);
            }
            return tb;
        }
    }
}